#include "SuckTheMinions.h"
#include "global_var.h"

//bGetDelay(const short, int&, bool) uses an external timekeeper(int & prevTime)
bool bGetDelay(const int delay, int & prevTime, bool bResetPrevTime)
{
	if(delay == 0) return true;
	int currTime = timeGetTime();
	if(prevTime == 0) prevTime = timeGetTime();

	if(currTime - prevTime > delay) {
		prevTime = (bResetPrevTime) ? 0 : timeGetTime();
		return true;
	}

	return false;
}

CEnemy::CEnemy(void)
{
	bRender = false;
}

CEnemy::~CEnemy(void)
{
}

SuckTheMinions::SuckTheMinions(void):Scene()
{
	GameRunning = GameGetReady = Player1WinFlag = false;
	GameTimeLeft = 30;

	Background = Object2D(800,600);
	Background.setPosition(400,300);
	Main_Title = Object2D(503,145);
	Main_Title.setPosition(400,150);
	Continue = Object2D(509,59);
	Continue.setPosition(400,450);
	TimeLeft_Tenth = Object2D(50,50);
	TimeLeft_Tenth.setPosition(370,550);
	TimeLeft_One = Object2D(50,50);
	TimeLeft_One.setPosition(400,550);
	TimeLeftChar = Object2D(27,38);
	TimeLeftChar.setPosition(430,555);
	MainTitlePrevTime = InstructPrevTime = GameRunPrevTime = CloudDraw = 0;
	for(int i = 0; i < 5; ++i)
		DrawInstruct[i] = false;

	Ready = Object2D(301,85);
	Ready.setPosition(400,300);
	Go = Object2D(137,87);
	Go.setPosition(400,300);
	DrawGo = false;
	GetReadyPrevTime = 0;

	Word_Player = Object2D(326,94);
	Word_Player.setPosition(400,250);
	Word_Wins = Object2D(249,87);
	Word_Wins.setPosition(400,350);
	EndGamePrevTime = 0;
	DrawContinue = false;

	theEnemy = new CEnemy[3];
	EnemyPrevTime = EnemyRenderTime = EnemyNotRenderTime = 0;
	P1_Score = P2_Score = 0;
	bRenderEnemy = isBeingSucked = false;

	Enemy_Cloud = Object2D(425/2, 312/2);
	Enemy_Cloud.setPosition(400,150);

	VacuumHeight = 670 / 4; VacuumWidth = 538 / 4;
	Player[PLAYER_ONE] = Player[PLAYER_TWO] = Object2D(VacuumWidth, VacuumHeight);
	Player[PLAYER_ONE].setPosition(160,350);
	Player[PLAYER_TWO].setPosition(640,350);

	ImageSize[RED] = Vector2D<float>(109,36);
	ImageSize[GREEN] = Vector2D<float>(121,37);
	ImageSize[BLUE] = Vector2D<float>(116,35);
	SceneImages[RED]	= Object2D(109,36);
	SceneImages[GREEN]	= Object2D(121,37);
	SceneImages[BLUE]	= Object2D(116,35);
	SceneImages[RED].setPosition	(400,350);
	SceneImages[GREEN].setPosition	(400,400);
	SceneImages[BLUE].setPosition	(400,450);
}

SuckTheMinions::~SuckTheMinions(void)
{
	if(theEnemy != NULL)
	{
		delete [] theEnemy;
		theEnemy = NULL;
	}
}

void SuckTheMinions::loadResource(void)
{
	//CLOUD IMAGE
	LoadTGA( &Image_Cloud[CLOUD_SMILE], "images/sucktheminions/Image_CloudSmile.tga", false);
	LoadTGA( &Image_Cloud[CLOUD_ANGRY], "images/sucktheminions/Image_CloudAngry.tga", false);

	//VACUUM IMAGE
	LoadTGA( &Image_Vacuum[PLAYER_ONE], "images/sucktheminions/Image_Player1_Vacuum.tga", false);
	LoadTGA( &Image_Vacuum[PLAYER_TWO], "images/sucktheminions/Image_Player2_Vacuum.tga", false);

	//BUTTON IMAGE
	LoadTGA( &Image_Instruct[RED], "images/sucktheminions/Instruct_Red.tga");
	LoadTGA( &Image_Instruct[GREEN], "images/sucktheminions/Instruct_Green.tga");
	LoadTGA( &Image_Instruct[BLUE], "images/sucktheminions/Instruct_Blue.tga");

	//BACKGROUND IMAGE
	LoadTGA( &Image_Background[0], "images/sucktheminions/Image_Background_MainTitle.tga");
	LoadTGA( &Image_Background[1], "images/sucktheminions/Image_Background_Game.tga");

	//MAIN TITLE
	LoadTGA( &Image_Main_Title[0], "images/sucktheminions/Main_Title.tga");
	LoadTGA( &Image_Main_Title[1], "images/sucktheminions/Image_Continue.tga");

	//GAME HUD
	Numbers[0] = new Sprite(10,1,"images/catchthegarbage/Image_Numbers.tga");
	LoadTGA( &Image_Char_S, "images/sucktheminions/Image_Second.tga");

	//READY IMAGE
	LoadTGA( &Image_Ready, "images/sucktheminions/Image_Ready.tga");
	LoadTGA( &Image_Go, "images/sucktheminions/Image_Go.tga");

	//END GAME
	LoadTGA( &Image_EndGame[0], "images/sucktheminions/Image_Player1.tga");
	LoadTGA( &Image_EndGame[1], "images/sucktheminions/Image_Player2.tga");
	LoadTGA( &Image_EndGame[2], "images/sucktheminions/Image_Wins.tga");
	LoadTGA( &Image_EndGame[3], "images/scorepage/Image_Continue.tga");
}

void SuckTheMinions::freeResource(void)
{
	freeTexture(&Image_Char_S);
	freeTexture(&Image_Ready);
	freeTexture(&Image_Go);

	for(int i = 0; i < 4; ++i)
	{
		if(i<2)
		{
			freeTexture(&Image_Background[i]);
			freeTexture(&Image_Main_Title[i]);
			freeTexture(&Image_Cloud[i]);
			freeTexture(&Image_Vacuum[i]);
		}
		if(i<3)
		{
			freeTexture(&Image_Instruct[i]);
		}

		freeTexture(&Image_EndGame[i]);
	}

}

void SuckTheMinions::reset(void)
{
	for(int i = 0; i < 3; ++i)
	{
		theEnemy[i].setRender(false);
	} 

	SuckTheMinions();
}

void SuckTheMinions::draw(void)
{
	if(!GameRunning && !GameGetReady && GameTimeLeft != 0)
	{
		Background.drawPlane(Image_Background[GameRunning].texID);
		Main_Title.drawPlane(Image_Main_Title[0].texID);

		if(CloudDraw < 5 && !DrawInstruct[CloudDraw] && bGetDelay((CloudDraw > 0)?1000:3000, MainTitlePrevTime)) 
		{
			DrawInstruct[CloudDraw] = true;
			if(CloudDraw > 1) DrawInstruct[CloudDraw-1] = false;
			CloudDraw++;
		}

		Player[0].setPosition(Player[0].getPosition().getX(),Player[0].getPosition().getY()+50);
		Enemy_Cloud.setPosition(Enemy_Cloud.getPosition().getX()+200, Enemy_Cloud.getPosition().getY()+200);

		if(DrawInstruct[0])
		{

			if(!DrawInstruct[4]) Player[0].drawPlane(Image_Vacuum[0].texID);
			if(DrawInstruct[1])
			{
				glColor3f(1,0,0);
			}
			else if(DrawInstruct[2])
			{
				glColor3f(0,1,0);
			}
			else if(DrawInstruct[3])
			{
				glColor3f(0,0,1);
			}
			else if(DrawInstruct[4])
			{
				Continue.drawPlane(Image_Main_Title[1].texID);
			}
		}

		if(CloudDraw > 1 && !DrawInstruct[4])
		{
			Enemy_Cloud.drawPlane(Image_Cloud[CLOUD_SMILE].texID);
			glColor3f(1,1,1);
			SceneImages[CloudDraw-2].drawPlane(Image_Instruct[CloudDraw-2].texID);
		}

		Enemy_Cloud.setPosition(Enemy_Cloud.getPosition().getX()-200, Enemy_Cloud.getPosition().getY()-200);
		Player[0].setPosition(Player[0].getPosition().getX(),Player[0].getPosition().getY()-50);
	}
	else if(GameGetReady && !GameRunning)
	{
		Background.drawPlane(Image_Background[0].texID);
		if(!DrawGo)
		{
			Ready.drawPlane(Image_Ready.texID);
		}
		else
		{
			Go.drawPlane(Image_Go.texID);
		}
	}
	else if (GameRunning)
	{
		glColor3f(1,1,1);
		Background.drawPlane(Image_Background[GameRunning].texID);
		if(GameTimeLeft/10 > 0)TimeLeft_Tenth.drawPlane(Numbers[0],GameTimeLeft/10);
		TimeLeft_One.drawPlane(Numbers[0],GameTimeLeft%10);;
		TimeLeftChar.drawPlane(Image_Char_S.texID);
		Player[PLAYER_ONE].drawPlane(Image_Vacuum[PLAYER_ONE].texID);
		Player[PLAYER_TWO].drawPlane(Image_Vacuum[PLAYER_TWO].texID);

		if(theEnemy[RED].getRender() == true)			glColor3f(1,0,0);	//Render RED
		else if(theEnemy[GREEN].getRender() == true)	glColor3f(0,1,0);	//Render GREEN
		else if(theEnemy[BLUE].getRender() == true)		glColor3f(0,0,1);	//Render BLUE
		else											glColor4f(0,0,0,0);	//Render nothing

		if(isBeingSucked == false)
		{
			Enemy_Cloud.drawPlane(Image_Cloud[CLOUD_SMILE].texID);
		}
		else
		{
			Enemy_Cloud.drawPlane(Image_Cloud[CLOUD_ANGRY].texID);
			if(bGetDelay(300, CloudPrevTime)) isBeingSucked = false;
		}

		glColor3f(1,1,1);
		printw(100, 500, 0, "Player 1 : %i", P1_Score);
		printw(550, 500, 0, "Player 2 : %i", P2_Score);
		SceneImages[RED].drawPlane	(Image_Instruct[RED].texID);
		SceneImages[GREEN].drawPlane(Image_Instruct[GREEN].texID);
		SceneImages[BLUE].drawPlane	(Image_Instruct[BLUE].texID);
	}
	else if(!GameRunning && GameTimeLeft == 0)
	{
		PlaySound("sounds/catchthegarbage/game_over.wav",NULL,SND_FILENAME|SND_ASYNC);
		Background.drawPlane(Image_Background[GameRunning].texID);
		Word_Player.drawPlane(Image_EndGame[!Player1WinFlag].texID);
		Word_Wins.drawPlane(Image_EndGame[2].texID);
		if(bGetDelay(1000,EndGamePrevTime)) DrawContinue = true;
		if(DrawContinue) Continue.drawPlane(Image_EndGame[3].texID);
		(Player1WinFlag)?LeaderBoard::getInstance().P1_AddScore():LeaderBoard::getInstance().P2_AddScore();
	}
}

void SuckTheMinions::update(void)
{
	if(EnemyRenderTime == 0)	EnemyRenderTime = 3000;
	if(EnemyNotRenderTime == 0) EnemyNotRenderTime = Randomizer::getInstance().randMax(1000,3000);
	if(EnemyRenderTime == 0)	EnemyRenderTime = 2000;

	if(GameRunning && GameTimeLeft > 0 && bGetDelay(1000,GameRunPrevTime))
		GameTimeLeft--;
	else if(GameTimeLeft == 0)
	{
		Player1WinFlag = (P1_Score > P2_Score) ? true : false;
		GameRunning = false;
	}
	
	if(GameGetReady && !GameRunning)
	{
		
		if(!DrawGo && bGetDelay(2000,GetReadyPrevTime)) 
		{
			DrawGo = true;
		}
		else if(DrawGo && bGetDelay(1000, GetReadyPrevTime))
		{
			GameGetReady = false;
			GameRunning = true;
		}
	}
	
	if((P1_Score + P2_Score) / 2 > 20)
	{
		EnemyNotRenderTime = 1000;
	}
	if((P1_Score + P2_Score) / 2 > 40)
	{
		EnemyRenderTime = 1000;
		EnemyNotRenderTime = 800;
	}
	if((P1_Score + P2_Score) / 2 < 50)
	{
		EnemyRenderTime = 2000;
		EnemyNotRenderTime = Randomizer::getInstance().randMax(1500,4000);
	}

	if(!bRenderEnemy && bGetDelay(EnemyNotRenderTime, EnemyPrevTime))
	{
		theEnemy[Randomizer::getInstance().randMax(3)].setRender(true);
		bRenderEnemy = true;
		EnemyNotRenderTime = 0;
	}
	else if(bRenderEnemy && bGetDelay(EnemyRenderTime,EnemyPrevTime))
	{
		for(int i = 0; i < 3; ++i) theEnemy[i].setRender(false);
		bRenderEnemy = false;
	}

	//Vacuum
	for(int i = 0; i < 2; ++i)
	{
		if(isSucking[i] == true)
		{
			if(Player[i].getHeight() == VacuumHeight)
			{
				Player[i].setWidth(Player[i].getWidth() + 5);
				Player[i].setHeight(Player[i].getHeight() + 5);
			}
			else if(bGetDelay(60,VacuumPrevTime))
			{
				Player[i].setWidth(VacuumWidth);
				Player[i].setHeight(VacuumHeight);
				isSucking[i] = false;
			}

		}
	}

	//SceneImages
	const int width_difference = 20;
	const int height_difference = 10;
	for(int i = 0; i < 3; ++i)
	{
		if(theEnemy[i].getRender() == true)
		{
			SceneImages[i].setWidth	(ImageSize[i].getX() + width_difference);
			SceneImages[i].setHeight(ImageSize[i].getY() + height_difference);
		}
		else if(SceneImages[i].getHeight() != ImageSize[i].getY())
		{
			SceneImages[i].setWidth	(ImageSize[i].getX());
			SceneImages[i].setHeight(ImageSize[i].getY());
		}
	}

	//AI
	if(_SinglePlayer)
	{
#define AI_REACTION_TIME 400
#define AI_ACTION_DELAY 130
		static int i = 0;
		static bool bScore;
		if(bScore && bGetDelay(AI_ACTION_DELAY, AIScoringPrevTime)) ScoreFunc(PLAYER_TWO, i);
		if(!theEnemy[i].getRender()) bScore = false;
		if(!bScore)
		{
			for(i = 0; i < 3; ++i)
			{
				if(theEnemy[i].getRender() && bGetDelay(AI_REACTION_TIME,AIReactionPrevTime))
				{
					bScore = true;
					break;
				}
			}
		}
	}
}

void SuckTheMinions::handleKeyboard(int key, int x, int y)
{
	switch(key)
	{
	case 27: glutLeaveMainLoop(); 
	//	SceneManager::getInstance().changeScene("Pause");
		break;
	default: break;
	}
}

void SuckTheMinions::handleKeyboardUp(int key, int x, int y)
{
	switch(key)
	{
	case ' ':
		PlaySound("sounds/games/go.wav", NULL,SND_ASYNC);
		if(!GameRunning && GameTimeLeft != 0) GameGetReady = true;
		else if(!GameRunning && GameTimeLeft == 0)
			SceneManager::getInstance().changeScene("Score_Board");
		break;
	case 'a':
	case 'A': //Player 1 RED
		ScoreFunc(PLAYER_ONE, RED);
		break;

	case 's':
	case 'S': //Player 1 GREEN
		ScoreFunc(PLAYER_ONE, GREEN);
		break;

	case 'd':
	case 'D': //Player 1 BLUE
		ScoreFunc(PLAYER_ONE, BLUE);
		break;

	case 'j':
	case 'J': //Player 2 RED
		if(!_SinglePlayer) ScoreFunc(PLAYER_TWO, RED);
		break;

	case 'k':
	case 'K': //Player 2 GREEN
		if(!_SinglePlayer) ScoreFunc(PLAYER_TWO, GREEN);
		break;
		
	case 'l':
	case 'L': //Player 2 BLUE
		if(!_SinglePlayer) ScoreFunc(PLAYER_TWO, BLUE);
		break;
	}
}

void SuckTheMinions::handleKeyboardSpecial(int key, int x, int y)
{
}

void SuckTheMinions::getMid(int &x, int &y)
{
}

void SuckTheMinions::handleMouseClick(int button, int state, int x, int y)
{
}

void SuckTheMinions::handleMouseMove(int x, int y)
{
}

void SuckTheMinions::ScoreFunc(bool Player2Flag, int EnemyChoice)
{
	if(theEnemy[EnemyChoice].getRender() == true)
	{
		(Player2Flag) ? ++P2_Score : ++P1_Score;
		((Player2Flag) ? isSucking[PLAYER_TWO] : isSucking[PLAYER_ONE]) = true;
		isBeingSucked = true;
		CloudPrevTime = 0;
	}
}